/**
 * @brief SSL服务器接口定义
 * @version 1.0
 * @author 宋炜
 */


#pragma once
#include <string>

#include <openssl/ssl.h>
#include <openssl/err.h>

#include "mallocSharedPtr.hpp"
#include "container/rbTree.hpp"
#include "threadPool.hpp"
#include "designM/command.hpp"
#include "container/variant.hpp"

class sslSvrConnection;

struct sslSvrItfc
{
public:
#if defined( WIN32 ) || defined( WINNT )
#    include <windows.h>
    using native_socket = SOCKET;
#elif defined( __LINUX__ )
	using native_socket = int;
#endif


    using connection_t = std::shared_ptr< sslSvrConnection >;
    using connData_t = wheels::rbTree< native_socket , connection_t >;

	enum class event
	{
		EVT_REQ_CONNECT,
		EVT_CONNECTED,
		EVT_CLOSE,
		EVT_DATA,
		EVT_ERROR
	};

	using dispatcher_t = wheels::dm::dispatcher< event >;
	struct evtData{
        connection_t                         m_conn;
		wheels::mallocSharedPtr< uint8_t >   m_data;
	};
protected:
	SSL_CTX           * p_ctx__;
	
	connData_t          m_connections__;  // 连接表
	wheels::threadPool  m_thd_pool__;     // 线程池
protected:
        
public:
	sslSvrItfc( const std::string& ca , const std::string& cert , const std::string& key );
    virtual ~sslSvrItfc(){
        auto * p_evt_loop = wheels::dm::mainLoop< event >::create();
        if( p_evt_loop ){
            p_evt_loop->stop();
            m_thd_pool__.start( false );
        }
	}
    /**
     * @brief 接收连接
     * @param sock[ I ]， 本地套接字，这个套接字是服务器监听套接字
     * @return 成功操作返回true，否则返回false
     */
	bool accept( native_socket sock );
    /**
     * @brief 根据本地套接字返回连接对象
     * @param h
     * @return 返回套接字指针
     */
	connection_t get( native_socket h );
	connection_t operator[]( native_socket h );

	void erase( native_socket h );

	uint32_t counts();

    wheels::dm::dispatcher<event> * getDispatcher();
};
